package baza.games.airSoccer;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;

public class AirSoccerEngine {
	 private ArrayList<IDrawableComponent> componets = new ArrayList<IDrawableComponent>();
	 
	 public static int netHeight = 0;
	 public static int netWidth = 0;
	 public static float atrito = 0.04F;
	 
	 public static int placar1 = 0;
	 public static int placar2 = 0;
	 
	 private Paddle paddle1;
	 private Paddle paddle2;
	 private SoccerField field;
	 private Ball ball;
	 private Traves trave1;
	 private Traves trave2;
	 private ConcurrentLinkedQueue<MotionEvent> lstEventosClicks = new ConcurrentLinkedQueue<MotionEvent>();
	 
	 
	 public AirSoccerEngine()
	 {
		    field = new SoccerField();
			field.setEngine(this);
		    this.addComponent(field);
			
			paddle1 = new Paddle(300, 300, Color.BLUE, PosicoesCampo.Cima);
			paddle1.setEngine(this);
			this.addComponent(paddle1);
			
			paddle2 = new Paddle(300, 600, Color.RED, PosicoesCampo.Baixo);
			paddle2.setEngine(this);
			this.addComponent(paddle2);
			
			ball = new Ball();
			ball.setEngine(this);
			this.addComponent(ball);
			
			trave1 = new Traves(PosicoesCampo.Cima);
			trave1.setEngine(this);
			this.addComponent(trave1);
			
			trave2 = new Traves(PosicoesCampo.Baixo);
			trave2.setEngine(this);
			this.addComponent(trave2);
	 }
	 
	 public void update()
	 {
		 PerformGols();

		 PerformCollision();
		 
		 for (IDrawableComponent component : componets) {
				component.update();
			}
	 }
	 private void PerformGols()
	 {
		 if( CheckForGol(trave1) )
		 {
			 AirSoccerEngine.placar2++;
			 this.ball.center();
		 }
		 if( CheckForGol(trave2) )
		 {
			 AirSoccerEngine.placar1++;
			 this.ball.center();
		 }
	 }
	 
	 private boolean CheckForGol(Traves trave)
	 {
		 boolean wasGol = false;
		 
		 if( this.ball.posX >= trave.x1 && this.ball.posX <= trave.x2 )
		 {
			 if(trave.posicaoCampo == PosicoesCampo.Cima)
			 {
				 //trocar 5 pela espessura da trave
				 if(this.ball.posY - this.ball.radio <= 5)
				 {
					 wasGol = true;
				 }
					 
			 }
			 else
			 {
				 if(this.ball.posY + this.ball.radio >= AirSoccerEngine.netHeight - 12)
				 {
					 wasGol = true;
				 }
			 }
		 }
		 
		 return wasGol;
	 }
	 
	 public boolean hasCollision(Paddle paddle, Ball ball)
	 {
		 //Paddle1 Colidiu ?
		 float dx = paddle.currX - ball.posX;
		 float dy = paddle.currY -  ball.posY;
		 double d = Math.sqrt((dx*dx) + (dy*dy));
		 
		 return (d <= paddle.radio + ball.radio);
	 }
	 
	 private void PerformCollision() {

		 //colodiu ?
		 if(this.hasCollision(this.paddle1, this.ball))
		 {
			ball.vx = (paddle1.getMass()* paddle1.getSpeedX()) / ball.getMass() ;
			ball.vy = (paddle1.getMass()* paddle1.getSpeedY()) / ball.getMass() ;
		 }
		 
		 if(this.hasCollision(this.paddle2, this.ball))
		 {
				ball.vx = ( paddle2.getMass()*  paddle2.getSpeedX()) / ball.getMass() ;
				ball.vy = ( paddle2.getMass()*  paddle2.getSpeedY()) / ball.getMass() ;
		 }

		 
		
	}

	public void doDraw(Canvas c)
	 {
		 ClearScreen(c);

		 for (IDrawableComponent component : componets) {
				component.draw(c);
			}
	 }
	 
     public void ClearScreen(Canvas c){
		 c.clipRect(0, 0, c.getWidth(), c.getHeight());
		 Paint paint = new Paint();
		 paint.setColor(Color.BLACK);
		 paint.setStyle(Paint.Style.FILL);
		 c.drawRect(0, 0, c.getWidth(), c.getHeight(), paint);
	 }
	 
	 public void addComponent(IDrawableComponent component)
	 {
			componets.add(component);
	 }

	public void doTouch(MotionEvent event) {
		this.lstEventosClicks.add(event);
		
	}

	public void processaInput() {
		
		if(lstEventosClicks.isEmpty())
			return;
		
		MotionEvent event = lstEventosClicks.remove();
		
		if(event.getAction() == MotionEvent.ACTION_DOWN ||
				event.getAction() == MotionEvent.ACTION_MOVE)
		{
			//padle1 < meio //padle2 > meio
			if(event.getY(0) > netHeight/2)
			{
				paddle2.SetPosition(event.getX(0), event.getY(0));
			}
			else
			{
				paddle1.SetPosition(event.getX(0), event.getY(0));
			}
			
			if(event.getPointerCount() > 1)
			{
				if(event.getY(1) > netHeight/2)
				{
					paddle2.SetPosition(event.getX(1), event.getY(1));
				}
				else
				{
					paddle1.SetPosition(event.getX(1), event.getY(1));
				}
			}
			
			this.colocaPaddlePosicaoValida(paddle1);
			this.colocaPaddlePosicaoValida(paddle2);
		}
	}

	public void colocaBolaPosicaoValida() {
		/*if(this.hasCollision(this.paddle1, ball2)){
			ball2.posX = paddle1.currX + ((paddle1.radio + ball2.radio) * Math.signum(paddle1.getSpeedX()));
			ball2.posY = paddle1.currY + ((paddle1.radio + ball2.radio) * Math.signum(paddle1.getSpeedY()));
		}
		if(this.hasCollision(this.paddle2, ball2)){
			ball2.posX = paddle2.currX + ((paddle2.radio + ball2.radio) * Math.signum(paddle2.getSpeedX()));
			ball2.posY = paddle2.currY + ((paddle2.radio + ball2.radio) * Math.signum(paddle2.getSpeedY()));
		}*/
		
		if(ball.posX - ball.radio <= 0)
			ball.posX = 1 + ball.radio;
		if(ball.posX + ball.radio >= AirSoccerEngine.netWidth)
			ball.posX = AirSoccerEngine.netWidth - ball.radio - 1;
		
		if(ball.posY - ball.radio <= 0)
			ball.posY = 1 + ball.radio;
		if(ball.posY + ball.radio >= AirSoccerEngine.netHeight)
			ball.posY = AirSoccerEngine.netHeight - ball.radio - 1;
		
	}

	public void colocaPaddlePosicaoValida(Paddle paddle) {
		//float somaBola = 0;
		/*
		if(this.hasCollision(paddle, this.ball)){
			//batendo da esquerda para direita
			if(paddle.currX > this.ball.posX){
				paddle.currX = this.ball.posX
			}
		}*/
		
		//logica para nao sair do campo
		if(paddle.currX - paddle.radio <= 0)
			paddle.currX = paddle.radio + 1;
		if(paddle.currX + paddle.radio >= AirSoccerEngine.netWidth)
			paddle.currX = AirSoccerEngine.netWidth - paddle.radio - 1;
		
		if(paddle.currY - paddle.radio <= 0)
			paddle.currY = 1 + paddle.radio;
		if(paddle.currY + paddle.radio >= AirSoccerEngine.netHeight)
			paddle.currY = AirSoccerEngine.netHeight - paddle.radio - 1;
		
		//logica para nao cruza o meio de campo
		if(paddle.posicaoCampo == PosicoesCampo.Cima)
		{
			if(paddle.currY + paddle.radio >= AirSoccerEngine.netHeight /2)
			{
				paddle.currY = ( AirSoccerEngine.netHeight /2) - paddle.radio;
			}
		}
		else
		{
			if(paddle.currY - paddle.radio < AirSoccerEngine.netHeight /2)
			{
				paddle.currY = ( AirSoccerEngine.netHeight /2) + paddle.radio;
			}
		}
		
	}

}
